package file

import (
	"api/config"
	"api/config/code"
	"api/libs/errs"
	"fmt"
	"gitee.com/dreamwood/ez"
	"gitee.com/dreamwood/ez/server"
	"os"
	path2 "path"
	"sort"
	"strings"
)

func init() {
	server.Do(&server.Router{Url: "/upload"}, Upload)
	server.Do(&server.Router{Url: "/vue_upload"}, VueUpload)
	server.Do(&server.Router{Url: "/folder"}, Picker)
}

func Upload(operation *server.Operation) {
	group := operation.Get("dir").IsString("upload")
	e := operation.Input.Request.ParseMultipartForm(500 * 1024 * 1024)
	if errs.Try(e) {
		Data := ez.M{
			"code":    code.Error,
			"message": "ParseMultipartForm Error",
			"data":    e.Error(),
		}
		operation.JsonOut(Data)
		return
	}
	for _, fileInfo := range operation.Input.Request.MultipartForm.File["file"] {
		data := make([]byte, fileInfo.Size)
		file, e := fileInfo.Open()
		if errs.Try(e) {
			Data := ez.M{
				"code":    code.Error,
				"message": fileInfo.Filename,
				"data":    e.Error(),
			}
			operation.JsonOut(Data)
			return
		}
		_, e = file.Read(data)
		if errs.Try(e) {
			Data := ez.M{
				"code":    code.Error,
				"message": fileInfo.Filename,
				"data":    e.Error(),
			}
			operation.JsonOut(Data)
			return
		}
		rnd := ez.CreateRandString(10)
		url := fmt.Sprintf("/static/%s/%s/%s_%s%s", group, ez.GetDateYMD(), ez.GetDateYMDHIS("", "", "_"), rnd, path2.Ext(fileInfo.Filename))
		path := fmt.Sprintf("./%s", url)
		ez.CreateFile(path, data)
		sizeFloat := float64(fileInfo.Size)
		size := fmt.Sprintf("%.0fB", sizeFloat)
		if sizeFloat > 1024 {
			size = fmt.Sprintf("%.3fKB", sizeFloat/1024)
		}
		if sizeFloat > 1024*1024 {
			size = fmt.Sprintf("%.3fMB", sizeFloat/1024/1024)
		}

		Data := ez.M{
			"code":    code.Success,
			"message": "上传成功",
			"data": ez.M{
				"name": fileInfo.Filename,
				"url":  fmt.Sprintf("/%s%s", config.GetApi().FileServerName, url),
				"size": size,
			},
		}
		operation.JsonOut(Data)
		return
	}
}
func VueUpload(operation *server.Operation) {
	group := operation.Get("dir").IsString("upload")
	e := operation.Input.Request.ParseMultipartForm(500 * 1024 * 1024)
	if errs.Try(e) {
		Data := ez.M{
			"errno": "1",
			"data":  e.Error(),
		}
		operation.JsonOut(Data)
		return
	}
	for _, fileInfo := range operation.Input.Request.MultipartForm.File["file"] {
		data := make([]byte, fileInfo.Size)
		file, e := fileInfo.Open()
		if errs.Try(e) {
			Data := ez.M{
				"errno": "1",
				"data":  e.Error(),
			}
			operation.JsonOut(Data)
			return
		}
		_, e = file.Read(data)
		if errs.Try(e) {
			Data := ez.M{
				"errno": "1",
				"data":  e.Error(),
			}
			operation.JsonOut(Data)
			return
		}
		rnd := ez.CreateRandString(10)
		url := fmt.Sprintf("/static/%s/%s/%s_%s%s", group, ez.GetDateYMD(), ez.GetDateYMDHIS("", "", "_"), rnd, path2.Ext(fileInfo.Filename))
		path := fmt.Sprintf("./%s", url)
		ez.CreateFile(path, data)
		Data := ez.M{
			"errno": "0",
			"data":  []string{fmt.Sprintf("http://%s:%d%s", config.GetCore().ServerHost, config.GetCore().ServerPort, url)},
		}
		operation.JsonOut(Data)
		return
	}
}

func Picker(operation *server.Operation) {
	root := operation.Get("root").IsString("/")
	root = strings.Replace(root, "\\", "/", -1)
	parts := strings.Split(root, "/")
	root = path2.Clean(root)
	if strings.HasSuffix(root, "/") {
		root = root[:len(root)-1]
	}

	exists := make([]string, 0)
	creates := make([]string, 0)
	for i, part := range parts {
		if part == "" {
			continue
		}
		checkExist := strings.Join(parts[:i+1], "/")
		_, e := os.Stat(checkExist)
		if e != nil {
			if os.IsExist(e) {
				exists = append(exists, part)
			} else {
				creates = append(creates, part)
			}
		} else {
			exists = append(exists, part)
		}
	}
	//首先检测给出的原始数据是不是一个目录
	_, e := os.Stat(root)
	rootDir := root
	dirs := make([]string, 0)
	if e != nil && os.IsNotExist(e) {
		rootDir = strings.Join(parts[:len(parts)-1], "/")
		matcherPrefix := ""
		if len(parts) > 0 {
			matcherPrefix = parts[len(parts)-1]
		}
		f, _ := os.ReadDir(rootDir)
		if f != nil {
			for _, info := range f {
				if info.IsDir() {
					if matcherPrefix != "" {
						if strings.Contains(info.Name(), matcherPrefix) {
							dirs = append(dirs, info.Name())
						}
						continue
					}
					dirs = append(dirs, info.Name())
				}

			}
			sort.Strings(dirs)
		}

	} else {
		//【坑】检测目标目录是否在当前项目所在的分区，如果是相同分区，根目录应该替换成/,
		//-----比如我的项目在D:/BeeRun,当试图读取D:时就会出错，需要替换成/
		thisDir, _ := os.Getwd()
		findRoot := strings.Split(thisDir, `\`)
		var f []os.DirEntry
		if len(findRoot) > 0 && strings.ToLower(findRoot[0]) == strings.ToLower(rootDir) {
			f, _ = os.ReadDir("/")
		} else {
			f, _ = os.ReadDir(rootDir)
		}
		if f != nil {
			for _, info := range f {
				if info.IsDir() {
					dirs = append(dirs, info.Name())
				}
			}
			sort.Strings(dirs)
		}
	}

	operation.JsonOut(ez.M{
		"code":    code.Success,
		"message": "PK",
		"data": ez.M{
			"choices":    dirs,
			"existed":    exists,
			"existedDir": strings.Join(exists, "/"),
			"created":    creates,
			"createdDir": strings.Join(creates, "/"),
		},
	})
}
